﻿////
//// System.ComponentModel.MemberDescriptor.cs
////
//// Author:
////  Miguel de Icaza (miguel@ximian.com)
////  Andreas Nahr (ClassDevelopment@A-SoftTech.com)
////  Ivan N. Zlatev <contact@i-nz.net>
////
//// (C) Ximian, Inc.  http://www.ximian.com
//// (C) 2003 Andreas Nahr
////
//
////
//// Permission is hereby granted, free of charge, to any person obtaining
//// a copy of this software and associated documentation files (the
//// "Software"), to deal in the Software without restriction, including
//// without limitation the rights to use, copy, modify, merge, publish,
//// distribute, sublicense, and/or sell copies of the Software, and to
//// permit persons to whom the Software is furnished to do so, subject to
//// the following conditions:
////
//// The above copyright notice and this permission notice shall be
//// included in all copies or substantial portions of the Software.
////
//// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
//// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
//// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
//// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
//// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
//// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
////
//
//using System;
//using System.Collections;
//using System.Reflection;
//using System.Runtime.InteropServices;
//using System.ComponentModel.Design;
//using System.Globalization;
//
//namespace System.ComponentModel
//{
//	[ComVisible(true)]
//	public abstract class MemberDescriptor
//	{
//		private string name;
//		private Attribute[] attrs; // only the attributes supplied in the ctor
//		private AttributeCollection attrCollection;
//		private static IComparer default_comparer;
//
//		protected MemberDescriptor(string name, Attribute[] attrs)
//		{
//			this.name = name;
//			this.attrs = attrs;
//		}
//
//		protected MemberDescriptor(MemberDescriptor reference, Attribute[] attrs)
//		{
//			name = reference.name;
//			this.attrs = attrs;
//		}
//
//		protected MemberDescriptor(string name)
//		{
//			this.name = name;
//		}
//
//		protected MemberDescriptor(MemberDescriptor reference)
//		{
//			name = reference.name;
//			attrs = reference.AttributeArray;
//		}
//
//		protected virtual Attribute[] AttributeArray
//		{
//			get
//			{
//				ArrayList list = new ArrayList();
//				if (attrs != null)
//					list.AddRange(attrs);
//				FillAttributes(list);
//				// For duplicate attributes, the last one added to the list is kept.
//				Hashtable attributes = new Hashtable();
//				foreach (Attribute attribute in list)
//					attributes[attribute.TypeId] = attribute;
//				Attribute[] attributesArray = new Attribute[attributes.Values.Count];
//				attributes.Values.CopyTo(attributesArray, 0);
//				return attributesArray;
//			}
//			set
//			{
//				attrs = value;
//			}
//		}
//
//		protected virtual void FillAttributes(System.Collections.IList attributeList)
//		{
//			// to be overriden
//		}
//
//		public virtual AttributeCollection Attributes
//		{
//			get
//			{
//				if (attrCollection == null)
//					attrCollection = CreateAttributeCollection();
//				return attrCollection;
//			}
//		}
//
//		protected virtual AttributeCollection CreateAttributeCollection()
//		{
//			return new AttributeCollection(AttributeArray);
//		}
//
//		public virtual string Category
//		{
//			get
//			{
//				return ((CategoryAttribute)Attributes[typeof(CategoryAttribute)]).Category;
//			}
//		}
//
//		public virtual string Description
//		{
//			get
//			{
//				foreach (Attribute attr in AttributeArray)
//					if (attr is DescriptionAttribute)
//						return ((DescriptionAttribute)attr).Description;
//				return string.Empty;
//			}
//		}
//
//		public virtual bool DesignTimeOnly
//		{
//			get
//			{
//				foreach (Attribute attr in AttributeArray)
//					if (attr is DesignOnlyAttribute)
//						return ((DesignOnlyAttribute)attr).IsDesignOnly;
//				return false;
//			}
//		}
//
//		public virtual string DisplayName
//		{
//			get
//			{
//#if NET_2_0
//				foreach (Attribute attr in AttributeArray)
//					if (attr is DisplayNameAttribute)
//						return ((DisplayNameAttribute) attr).DisplayName;
//#endif
//				return name;
//			}
//		}
//
//		public virtual string Name
//		{
//			get
//			{
//				return name;
//			}
//		}
//
//		public virtual bool IsBrowsable
//		{
//			get
//			{
//				foreach (Attribute attr in AttributeArray)
//					if (attr is BrowsableAttribute)
//						return ((BrowsableAttribute)attr).Browsable;
//				return true;
//			}
//		}
//
//		protected virtual int NameHashCode
//		{
//			get
//			{
//				return name.GetHashCode();
//			}
//		}
//
//		public override int GetHashCode()
//		{
//			return base.GetHashCode();
//		}
//
//		public override bool Equals(object obj)
//		{
//			MemberDescriptor other = obj as MemberDescriptor;
//			if (other == null)
//				return false;
//			return other.name == name;
//		}
//
//		protected static ISite GetSite(object component)
//		{
//			if (component is Component)
//				return ((Component)component).Site;
//			else
//				return null;
//		}
//
//#if NET_2_0
//		[Obsolete ("Use GetInvocationTarget")]
//#endif
//		protected static object GetInvokee(Type componentClass, object component)
//		{
//			if (component is IComponent)
//			{
//				ISite site = ((IComponent)component).Site;
//				if (site != null && site.DesignMode)
//				{
//					IDesignerHost host = site.GetService(typeof(IDesignerHost)) as IDesignerHost;
//					if (host != null)
//					{
//						IDesigner designer = host.GetDesigner((IComponent)component);
//						if (designer != null && componentClass.IsInstanceOfType(designer))
//						{
//							component = designer;
//						}
//					}
//				}
//			}
//			return component;
//		}
//
//#if NET_2_0
//		protected virtual object GetInvocationTarget (Type type, object instance)
//		{
//			if (type == null)
//				throw new ArgumentNullException ("type");
//			if (instance == null)
//				throw new ArgumentNullException ("instance");
//
//			return GetInvokee (type, instance);
//		}
//#endif
//
//		protected static MethodInfo FindMethod(Type componentClass, string name, Type[] args, Type returnType)
//		{
//			return FindMethod(componentClass, name, args, returnType, true);
//		}
//
//		protected static MethodInfo FindMethod(Type componentClass, string name, Type[] args, Type returnType, bool publicOnly)
//		{
//			BindingFlags bf;
//			if (publicOnly == true)
//				bf = BindingFlags.Public;
//			else
//				bf = BindingFlags.NonPublic | BindingFlags.Public;
//			// FIXME returnType is not taken into account. AFAIK methods are not allowed to only
//			// differ by return type anyway
//			return componentClass.GetMethod(name, bf, null, CallingConventions.Any, args, null);
//		}
//
//		internal static IComparer DefaultComparer
//		{
//			get
//			{
//				if (default_comparer == null)
//					default_comparer = new MemberDescriptorComparer();
//				return default_comparer;
//			}
//		}
//
//		private class MemberDescriptorComparer : IComparer
//		{
//			public int Compare(object x, object y)
//			{
//				return String.Compare(((MemberDescriptor)x).Name, ((MemberDescriptor)y).Name,
//							   false, CultureInfo.InvariantCulture);
//			}
//		}
//	}
//}